<template>
  <div>
    <vxe-toolbar
      custom
      print
      export
      zoom
      v-if="toolbar"
      :refresh="{query: loadData}"
    >
      <template v-slot:buttons>
        <slot name="buttons"></slot>
        <a-radio-group
          name="radioGroup"
          :default-value="radioList[0].value"
          v-if="radioList.length > 0"
          style="float: right;margin: auto 100px"
          @change="handleChange">
          <a-radio :value="item.value" v-for="(item,index) in radioList" :key="index">{{ item.label }}</a-radio>
        </a-radio-group>
      </template>
    </vxe-toolbar>
    <vxe-table
      border
      row-key
      column-key
      ref="xTable"
      show-header-overflow
      show-overflow
      highlight-hover-row
      resizable
      export-config
      :data="localDataSource"
      @sort-change="sortChangeEvent"
      @checkbox-change="selectChangeEvent"
      @checkbox-all="selectAllEvent"
      :loading="localLoading"
      highlight-current-row
      :height="height"
      :keyboard-config="{isArrow: true}"
      :checkbox-config="{strict: true,checkMethod:checCheckboxkMethod2}"
      @current-change="checkboxSelect"
      @cell-click="cellClick"
      v-on="$listeners"
      :row-style="rowStyle"
      :cell-class-name="cellClassName"
      :show-footer="true"
      :footer-method="footerMethod"
      :span-method="spanMethod"
    >
      <!--展开行开始 update by pqz-->
      <vxe-table-column v-if="expand" type="expand" width="60">
        <template v-slot:content="{ row, rowIndex }">
        <vxe-table
          row-key
          column-key
          size="small"
          height="200"
          show-header-overflow
          show-overflow
          highlight-hover-row
          resizable
          @checkbox-change="expandSelectChangeEvent"
          :checkbox-config="{strict: true,checkMethod:checCheckboxkMethod3}"
          @checkbox-all="expandSelectAllEvent"
          :data="row.detailList"
          :row-config="{height: 10}"
        >
          <vxe-table-column type="checkbox" width="60" v-if="checkboxExpand"></vxe-table-column>
          <vxe-table-column type="radio" width="60" v-if="radio"></vxe-table-column>
          <template v-for="(column,index) in tableColumnChild">
            <vxe-table-column
              v-if="!column.hidden"
              :key="index"
              :field="column.field"
              :title="column.title"
              :sortable="column.sortable || false"
              :width="column.width || 200"
              :fixed="column.fixed"
              :align="column.align"
            >
              <template v-slot:header v-if="column.linkHeader">
                <router-link :to="{ name: column.linkName}">{{ column.title }}</router-link>
              </template>
              <template slot-scope="scope">
                <span v-if="column.slot != true">
                  {{ scope.row[column.field] }}
                </span>
                <slot
                  :row="scope.row"
                  :text="scope.row[column.field]"
                  v-else-if="column.slot"
                  :name="column.field"
                >
                </slot>
                <template v-else>
              <span v-if="['url'].includes(column.type)">
                <a
                  :href="scope.row[column.field]"
                  :target="column.target || '_blank'">{{ scope.row[column.field] }}</a>
              </span>
                </template>
              </template>
            </vxe-table-column>
          </template>
        </vxe-table>
        </template>
      </vxe-table-column>
      <!--展开行结束 update by pqz-->
      <vxe-table-column type="checkbox" width="60" v-if="checkbox"></vxe-table-column>
      <vxe-table-column type="radio" width="60" v-if="radio"></vxe-table-column>
      <template v-for="(column,index) in tableColumn">
        <vxe-table-column
          v-if="!column.hidden"
          :key="index"
          :field="column.field"
          :title="column.title"
          :sortable="column.sortable || false"
          :width="column.width || 200"
          :fixed="column.fixed"
          :align="column.align"
        >
          <template v-slot:header v-if="column.linkHeader">
            <router-link :to="{ name: column.linkName}">{{ column.title }}</router-link>
          </template>
          <template v-slot:header v-if="column.checkbox">
          </template>
          <template v-slot:header v-else-if="column.remark">
            {{ column.title }}
            <a-tooltip>
              <template slot="title">
                {{column.remark}}
              </template>
              <a-icon type="question-circle" />
            </a-tooltip>
          </template>
          <template slot-scope="scope">
            <span v-if="column.slot != true">
              {{ scope.row[column.field] }}
            </span>
            <slot
              :row="scope.row"
              :index="scope.rowIndex"
              :text="scope.row[column.field]"
              v-else-if="column.slot"
              :name="column.field"
            >
            </slot>
            <template v-else>
              <span v-if="['url'].includes(column.type)">
                <a
                  :href="scope.row[column.field]"
                  :target="column.target || '_blank'">{{ scope.row[column.field] }}</a>
              </span>
            </template>
          </template>
        </vxe-table-column>
      </template>
    </vxe-table>
    <vxe-pager
      border
      v-if="showPagination"
      size="medium"
      :loading="localLoading"
      :current-page="localPagination.currentPage"
      :page-size="localPagination.pageSize"
      :total="localPagination.total"
      :layouts="['PrevPage', 'JumpNumber', 'NextPage', 'FullJump', 'Sizes', 'Total']"
      @page-change="handlePageChange">
    </vxe-pager>
  </div>

</template>

<script>
import Sortable from 'sortablejs'

export default {
  name: 'VTable',
  data () {
    return {
      localDataSource: [],
      localLoading: false,
      localPagination: {
        currentPage: 1,
        pageSize: 50,
        total: 0
      },
      localParams: {}
    }
  },
  props: {
    spanMethod: {
      type: Function,
      default: function () {
        return () => {
        }
      }
    },
    footerMethod: {
      type: [Array, Function],
      default: function () {
        return () => []
      }
    },
    drop: {
      type: Boolean,
      default: true
    },
    height: {
      type: Number,
      default: 600
    },
    checkbox: {
      type: Boolean,
      default: false
    },
    checkboxExpand: {
      type: Boolean,
      default: false
    },
    //展开行参数
    expand: {
      type: Boolean,
      default: false
    },
    radio: {
      type: Boolean,
      default: false
    },
    radioList: {
      type: Array,
      default: function () {
        return []
      }
    },
    toolbar: {
      type: Boolean,
      default: false
    },
    tableColumn: {
      type: Array,
      default: function () {
        return []
      }
    },
    //展开行相关参数
    tableColumnChild: {
      type: Array,
      default: function () {
        return []
      }
    },
    data: {
      type: Function,
      required: true
    },
    pageNum: {
      type: Number,
      default: 1
    },
    pageSize: {
      type: Number,
      default: 50
    },
    bordered: {
      type: Boolean,
      default: true
    },
    showPagination: {
      type: Boolean,
      default: true
    },
    cellClick: {
      type: Function,
      default: function () {
        return () => {
        }
      }
    },
    selectAllEvent: {
      type: Function,
      default: function () {
        return () => {
        }
      }
    },
    // checCheckboxkMethod2: {
    //   type: Function,
    //   default: function () {
    //     return () => {}
    //   }
    // },
    selectChangeEvent: {
      type: Function,
      default: function () {
        return () => {
        }
      }
    },
    //子表行选中change
    expandSelectChangeEvent: {
      type: Function,
      default: function () {
        return () => {
        }
      }
    },
    //子表全勾选
    expandSelectAllEvent: {
      type: Function,
      default: function () {
        return () => {
        }
      }
    },
    rowStyle: {
      type: Function,
      default: function () {
        return () => {
        }
      }
    },
    cellClassName: {
      type: Function,
      default: function () {
        return () => {
        }
      }
    },
    checkboxConfig: {
      type: Function,
      default: function () {
        return () => {
        }
      }
    },
    checkboxRowSelect: {
      type: Function,
      default: function () {
        return () => {
        }
      }
    },

      checkboxConfigChild: {
          type: Function,
          default: function () {
              return () => {
              }
          }
      }
  },
  beforeDestroy () {
    if (this.sortable) {
      this.sortable.destroy()
    }
  },
  methods: {
    hideColumns(field){
      const ref = this.$refs.xTable
        ref.hideColumn(ref.getColumnByField(field))
    },
    showColumns(field){
        const ref = this.$refs.xTable
        ref.showColumn(ref.getColumnByField(field))
    },
    // 当排序条件发生变化时会触发该事件
    sortChangeEvent ({ column, property, order }) {
      let orders = order
      if (order) {
        orders = order === 'desc' ? 'descend' : 'ascend'
      } else {
        property = ''
      }
      this.loadData(this.localPagination, {}, {
        field: property,
        order: orders
      })
    },
    // 分页发生改变时会触发该事件
    handlePageChange ({ currentPage, pageSize }) {
      this.loadData({ currentPage, pageSize })
    },
    loadData (pagination, filters, sorter, params) {
      this.localLoading = true
      console.log('loadData')
      let parameter = {}
      if (this.showPagination) {
        parameter = Object.assign(parameter, {
          current: (pagination && pagination.currentPage) ||
            this.localPagination.currentPage || this.pageNum,
          size: (pagination && pagination.pageSize) ||
            this.localPagination.pageSize || this.pageSize
        })
      }

      parameter = Object.assign(parameter,
        (sorter && sorter.field && {
          sortField: sorter.field
        }) || {},
        (sorter && sorter.order && {
          sortOrder: sorter.order
        }) || {}, {
          ...filters
        }, { ...this.localParams }
      )
      const result = this.data(parameter)

      if ((typeof result === 'object' || typeof result === 'function') && typeof result.then === 'function') {
        result.then(r => {
          if (this.showPagination) {
            this.localPagination = Object.assign({}, this.localPagination, {
              currentPage: Number(r.current), // 返回结果中的当前分页数
              total: Number(r.total), // 返回结果中的总记录数
              pageSize: (pagination && pagination.pageSize) ||
                this.localPagination.pageSize
            })
            // 为防止删除数据后导致页面当前页面数据长度为 0 ,自动翻页到上一页
            if (r.records.length === 0 && this.localPagination.currentPage !== 1) {
              this.localPagination.currentPage--
              this.loadData()
              return
            }
            this.localDataSource = r.records // 返回结果中的数组数据
          } else {
            this.localDataSource = r
          }
          this.$emit('changeData', this.localDataSource)
        }).catch(err => {
          this.$message.error(err.msg)
        }).finally(_ => {
          this.localLoading = false
        })
      }
    },


    // 列拖拽
    columnDrop () {
      this.$nextTick(() => {
        const xTable = this.$refs.xTable
        this.sortable = Sortable.create(xTable.$el.querySelector('.body--wrapper>.vxe-table--header .vxe-header--row'), {
          handle: '.vxe-header--column:not(.col--fixed)',
          onEnd: ({ item, newIndex, oldIndex }) => {
            const { fullColumn, tableColumn } = xTable.getTableColumn()
            const targetThElem = item
            const wrapperElem = targetThElem.parentNode
            const newColumn = fullColumn[newIndex]
            if (newColumn.fixed) {
              // 错误的移动
              if (newIndex > oldIndex) {
                wrapperElem.insertBefore(targetThElem, wrapperElem.children[oldIndex])
              } else {
                wrapperElem.insertBefore(wrapperElem.children[oldIndex], targetThElem)
              }
              return this.$XModal.message({ message: '固定列不允许拖动！', status: 'error' })
            }
            // 转换真实索引
            const oldColumnIndex = xTable.getColumnIndex(tableColumn[oldIndex])
            const newColumnIndex = xTable.getColumnIndex(tableColumn[newIndex])
            // 移动到目标列
            const currRow = fullColumn.splice(oldColumnIndex, 1)[0]
            fullColumn.splice(newColumnIndex, 0, currRow)
            xTable.loadColumn(fullColumn)
          }
        })
      })
    },
    rowDrop () {
      this.$nextTick(() => {
        const xTable = this.$refs.xTable
        this.sortable = Sortable.create(xTable.$el.querySelector('.body--wrapper>.vxe-table--body tbody'), {
          handle: '.drag-btn',
          onEnd: ({ newIndex, oldIndex }) => {
            console.log(newIndex, oldIndex, 'newIndex, oldIndex')
            const currRow = this.localDataSource.splice(oldIndex, 1)[0]
            this.localDataSource.splice(newIndex, 0, currRow)
            this.$emit('changeData', this.localDataSource)
          }
        })
      })
    },
    refresh (bool = false) {
      this.loadData()
    },
    loadingShow() {
      this.localLoading = true
    },
    loadingFalse() {
      this.localLoading = false
    },
    handleChange (e) {
      this.localParams = Object.assign({}, this.localParams, {
        radio: e.target.value
      })
      this.loadData()
    },
    // eslint-disable-next-line vue/no-dupe-keys
    checCheckboxkMethod2 ({ row }) {
      return this.checkboxConfig({ row })
    },
    checkboxSelect ({ row }){
      return this.checkboxRowSelect({ row })
    },
    checCheckboxkMethod3 ({ row }) {
      return this.checkboxConfigChild({ row })
    }
  },
  created () {
    this.loadData()
    if (this.drop) {
      this.columnDrop()
      this.rowDrop()
    }
  }
}

</script>

<style scoped>


</style>
